Ext.namespace('App', 'App.user');
/**
 * App.document.Grid
 * A typical EditorGridPanel extension.
 */
App.user.UserManager = Ext.extend(Ext.Window, {
	//applyTo:'hello-win',
	id: 'userDialog',
	layout:'fit',
	width:600,
	height:300,
	closeAction:'hide',
	plain: true,
	title: 'Administrador de Usuarios',
	modal: true,
	//maximizable: true,
	maximized: true,
	iconCls: 'user-edit',
    layout: 'border',
    layoutConfig: {
        columns: 1
    },
	
	grid: null,
	form: null,
	application: null,
	record: null,
	
	// these two properties are to hold a reference to both field for dynamic manipulation 
	usernameField: null,
	emailField: null,
	oldPasswordField: null,
	passwordField: null,
	password2Field: null,
	rolesField: null,
	activeField: null,
	
	registerButton: null,
	
	FIELDMESSAGE_BLANKTEXT: 'Este campo es requerido.',
	FIELDMESSAGE_INVALIDTEXT: 'El valor entrado es inv&aacute;lido.',
	
	buttonUpdateText: 'Actualizar',
	buttonRegisterText: 'Registrar',
	
	/**
	 * 
	 */
	initComponent : function() {
    	// typical viewConfig
        this.viewConfig = {
            forceFit: true
        };
	
		this.grid = this.buildGrid();
		this.form = this.buildForm();
		
		// TODO: change this code to an adequate place 
		// this is a patch to get the register button component
		if( this.registerButton == null ) {
         	this.registerButton = Ext.getCmp('register-button');
     	}
		
		this.setFormDefaultField();
		//this.grid.bbar = this.buildBottomToolbar();
		
		this.items = [this.form, this.grid];
		
		this.grid.on('rowclick', this.onGridRowClick, this);
		
		/*
		 rowclick: function(g, index, ev) {
            var rec = g.store.getAt(index);
            userForm.loadRecord(rec);
        },
        destroy : function() {
            userForm.getForm().reset();
        }
        */
		
		this.on('show', function() {
			this.store.load();
			//Ext.getCmp('regUsername').focus(true, true);
		}, this.grid);
		
        // super
        App.user.UserManager.superclass.initComponent.call(this);
    },
    
    /**
     * 
     */
    buildGrid: function() {
    	var User = Ext.data.Record.create([{
	            name: 'uid',
	            mapping: 'uid'
	        }, {
	            name: 'username',
	            mapping: 'username',
	            type: 'string'
	        }, {
	            name: 'password',
	            mapping: 'password',
	            type: 'string'
	        }, {
	            name: 'email',
	            mapping: 'email',
	            type: 'string'
	        }, {
	            name: 'access',
	            mapping: 'access',
	            type: 'date'
	        }, {
	            name: 'login',
	            mapping: 'login',
	            type: 'date'
	        },{
	            name: 'status',
	            mapping: 'status',
	            type: 'boolean'
	        }, {
	            name: 'created_at',
	            mapping: 'created_at'
	        }, {
	        	name: 'roles',
	        	mapping: 'roles'
	        }, {
	        	name: 'encrytedPassword',
	        	type: 'string'
	        }]);

    	var userProxy = new Ext.data.HttpProxy({
	    		api: {
		    		read: BASE_URL + 'users/read',
		    		create: BASE_URL + 'users/create', 
		    		update: BASE_URL + 'users/update',
		    		destroy: BASE_URL + 'users/delete'
				},
				method: 'POST',
				listeners: {
					write: function(dp, action, data, response, rs, options ) {
					}
				}
    		});
    	
    	// create the Reader with userRecord
    	var userReader = new Ext.data.JsonReader({
	    	    totalProperty: 'users',
	    	    successProperty: 'success',
	    	    messageProperty: 'message',  // <-- New "messageProperty" meta-data
	    	    idProperty: 'uid',
	    	    root: 'data',
	    	    fields: User
    		});

    	var userWriter = new Ext.data.JsonWriter({
	    	    encode: true,
	    	    writeAllFields: false
    		});

    	//Typical Store collecting the Proxy, Reader and Writer together.
    	var userStore = new Ext.data.GroupingStore({
    			proxy: userProxy,
	    	    reader: userReader,
	    	    writer: userWriter, // <-- plug a DataWriter into the store just as you would a Reader
	    	    sortInfo:{field: 'created_at', direction: "ASC"},
	    	    //groupField:'documentType',
	    	    autoSave: false, 
	    	    loadMask: true
    		});
    	
    	var editor = new Ext.ux.grid.RowEditor({
            saveText: 'Update'
        });
    	
    	var columnModel = new Ext.grid.ColumnModel([
        	{header: "Id", dataIndex: 'uid', sortable: true},
        	{header: "Usuario", dataIndex: 'username', sortable: true/*, editor: {xtype: 'textfield', allowBlank: false}*/},
        	{header: "Email", width: 150, dataIndex: 'email', sortable: true/*, editor: {xtype: 'textfield', allowBlank: false, vtype: 'email'}*/},
        	{header: "Adicionado", dataIndex: 'created_at', sortable: true, renderer: formatDateRenderer},
        	{header: "Activo", dataIndex: 'status', align: 'center', width: 50, renderer: userStatusRenderer},
        	{header: "encryptedPassword", dataIndex: 'encryptedPassword', hidden: true},
        	//{header: "Activo", xtype: 'booleancolumn', dataIndex: 'status', align: 'center', width: 50, trueText: 'Si', falseText: 'No'/*, editor: {xtype: 'checkbox'}*/},
    	]);
    	
    	var _this = this;
    	var grid = new Ext.grid.GridPanel({
    	        store: userStore,
    	        width: 800,
    	        height: 700,
    	        region:'center',
    	        margins: '5 5 5 5',
    	        cm: columnModel,
    	        //autoExpandColumn: 'username',
    	        //plugins: [editor],
    	        view: new Ext.grid.GroupingView({
    	           // markDirty: false
    	        	forceFit: true
    	        }),
    	        sm: new Ext.grid.RowSelectionModel({ 
    	        	singleSelect: true
    	        }),
    	        tbar: [{
    	            iconCls: 'icon-user-add',
    	            text: 'Adicionar Usuario',
    	            handler: this.onAddNewUser
    	        },{
    	            ref: '../removeBtn',
    	            iconCls: 'icon-user-delete',
    	            text: 'Eliminar Usuario',
    	            disabled: true,
    	            handler: function() {
    	                editor.stopEditing();
    	                var s = grid.getSelectionModel().getSelections();
    	                for(var i = 0, r; r = s[i]; i++){
    	                	userStore.remove(r);
    	                }
    	                userStore.save();
    	            }
    	        }],
    	        bbar: new Ext.PagingToolbar({
    		        store: userStore,
    		        pageSize: 20,
    		        hideBorders: true})
    	    });
    	
    	return grid;
    },
    
    /**
     * 
     */
    buildBottomToolbar : function() {
    	var paginationToolbar = new Ext.PagingToolbar({
	        store: this.grid.store,
	        pageSize: 50,
	        hideBorders: true
	    });
    	return paginationToolbar;
    },
    
    /**
     * 
     */
    buildForm: function() {
    	var formUser = new Ext.form.FormPanel({
		        iconCls: 'silk-user',
		        frame: false,
		        labelAlign: 'right',
		        title: 'Usuario -- Todos los campos son obligatorios',
		        width:600,
		        height:350,
		        trackResetOnLoad: true,
		        labelWidth: 130,
		        //layout: '',
		        
		        defaults: {
		            //anchor: '5'
		        },
		        
		        bodyStyle: 'padding:10px 10px 15px 15px; background:#dfe8f6; ',
		        style:'text-align:left',
		        //layout:'fit',
		        margins: '5 5 5 5',
		        region: 'north',
		        split: true,
		        minHeight: 350,
		        
		        /*
		        frame: false, border: false, buttonAlign: 'center',
	    		url: BASE_URL + 'users/register', method: 'POST', id: 'frmRegister',
	    		bodyStyle: 'padding:10px 10px 15px 15px;background:#dfe8f6;',
	    		width: 300, labelWidth: 150,
		*/
		        // private A pointer to the currently loaded record
		        //record : null,
		    	/*
		        items: [
		    	{
					xtype: 'hidden',
		    		//xtype: 'textfield',
					value: myApp.sessionId,
					id: 'hiddenSeed'
				}],
		    	*/
		    	listeners: {
			        beforeaction: function() {
	                    if (formUser.getForm().isValid()) {
	                    }
	                }	
		        },
	    		buttons: [
	    			{ text: this.buttonRegisterText, id: 'register-button', handler: this.onRegisterOrUpdateUser, scope: this, disabled: false },
	    			{ text: 'Reset', handler: function() {
	    					formUser.getForm().reset();
	    				}
	    			}
	    		]
	    		
    	});

    	return formUser;
    },
    
    /**
     * 
     */
    setFormDefaultField: function() {
    	var store = new Ext.data.JsonStore({
    		proxy: new Ext.data.HttpProxy({
    			url: BASE_URL + 'roles/getRoles',
    			method: 'POST'
    		}),
    		fields: ['id','name'],
    		root: 'rows',
    		autoLoad: true,
    		sortInfo: {
    		    field: 'id',
    		    direction: 'ASC' // or 'DESC' (case sensitive for local sorting)
    		},
    		listeners: {
    			load: function( /*Store this*/s, /*Ext.data.Record[]*/ records, /*Object*/ options ) {
    				// remove the 'usuario anonimo' from the store
    				s.removeAt(1);
    			}
    		}
    	});
    	
    	this.usernameField = new Ext.form.TextField({
    		//xtype: 'textfield',
			fieldLabel: 'Nombre de usuario',
			name: 'username',
			id: 'regUsername',
			allowBlank: false,
            vtype: 'uniqueusername',
            width: 300,
            msgTarget: 'side',
            //listeners:{change: this.onChange}, 
            blankText: this.FIELDMESSAGE_BLANKTEXT, 
            invalidText: this.FIELDMESSAGE_INVALIDTEXT,
            listeners: {change: this.onChange},
	    });
    	
    	this.currentPasswordField = new Ext.form.TextField({
    		fieldLabel: 'Contrase&ntilde;a actual',
			name: 'current-password',
			allowBlank: false,
			inputType: 'password',
            vtype: 'currentPassword',
            id: 'current-password',
            width: 300,
            msgTarget: 'side',
            //validationEvent: false,
            blankText: this.FIELDMESSAGE_BLANKTEXT, 
            invalidText: this.FIELDMESSAGE_INVALIDTEXT
    	});
    	
    	this.passwordField = new Ext.form.TextField({
			fieldLabel: 'Contrase&ntilde;a',
			name: 'password',
			allowBlank: false,
			inputType: 'password',
            vtype: 'passwordlength',
            id: 'password1',
            width: 300,
            msgTarget: 'side',
            blankText: this.FIELDMESSAGE_BLANKTEXT, 
            invalidText: this.FIELDMESSAGE_INVALIDTEXT,
            listeners: {change: this.onChange},
    	});
    	
    	this.password2Field = new Ext.form.TextField({
			fieldLabel: 'Confirmar contrase&ntilde;a',
			name: 'cpassword',
			allowBlank: false,
			inputType: 'password',
            id: 'password2',
            initialPassField: 'password1',
            vtype: 'password',
            width: 300,
            msgTarget: 'side',
            blankText: this.FIELDMESSAGE_BLANKTEXT, 
            invalidText: this.FIELDMESSAGE_INVALIDTEXT
    	});
    	
    	this.emailField = new Ext.form.TextField({
    		//xtype: 'textfield',
			fieldLabel: 'Email',
            id: 'regEmail',
			name: 'email',
			vtype:'uniqueemail',
			allowBlank: false,
			width: 300,
			msgTarget: 'side',
			blankText: this.FIELDMESSAGE_BLANKTEXT, 
            invalidText: this.FIELDMESSAGE_INVALIDTEXT,
            listeners: {change: this.onChange},
            //validationEvent: ''
    	});
    	
    	this.rolesField = new Ext.ux.form.ItemSelector({
    		xtype: 'itemselector',
            name: 'roles',
            bodyStyle: 'padding:5px 10px 5px 10px;',
            fieldLabel: 'Roles',
	        imagePath: 'application/resources/js/ext_plugins/images/',
	        availableText: 'Disponibles',
	        selectedText: 'Seleccionado',
	        width: 540,
            multiselects: [{
                width: 250,
                height: 130,
                store: store,
                displayField: 'name',
                valueField: 'id'
            },{
                width: 250,
                height: 130,
                store: new Ext.data.JsonStore({
            		fields: ['id','name']
            	}),
                displayField: 'name',
                valueField: 'id',
                tbar:[{
                    text: 'Limpiar',
                    handler:function(){
                		formUser.getForm().findField('roles').reset();
	                }
                }]
            }],
            listeners: {change: this.onChange}
    	});
    	
    	this.activeField = new Ext.form.Checkbox({
    		xtype: 'checkbox', 
    		fieldLabel: 'Activo', 
    		name: 'status',
    		listeners: {change: this.onChange},
    	});
    	
    	this.form.add(this.usernameField);
    	this.form.add(this.passwordField);
    	this.form.add(this.password2Field);
    	this.form.add(this.emailField);
    	this.form.add(this.rolesField);
    	this.form.add(this.activeField);
    	this.form.add({xtype: 'hidden', value: '',	id: 'encrytedPassword', name: 'encrytedPassword'});
    	this.form.add({xtype: 'hidden', value: myApp.sessionId,	id: 'hiddenSeed'});
    	
    	this.form.doLayout();
    },

    /**
     * 
     */
    onGridRowClick: function(g, index, ev) {
    	this.record = g.store.getAt(index);
    	
    	// enable or disable the 'Eliminar Usuario' button
		g.removeBtn.setDisabled( (["1", "2"].indexOf(this.record.id) != -1) ? true : false);
    	
    	this.setFieldsConfiguration();
    	
    	this.record.data.password = '';
    	// reset the roles ItemSelector
    	this.rolesField.reset();
    	
    	if(this.record.data.roles != '') {
	    	var strRoles = this.record.data.roles.split(',');
	    	// we should convert the strRoles from string array to int array
	    	var roles = [];
	    	for( var i = 0; i < strRoles.length; i++ ) {
	    		roles.push(parseInt(strRoles[i])-1);
	    	}
	    	// autoselect the roles and call the fromTo function to muve the selection to the 
	    	// selected listView frame.
	    	this.rolesField.fromMultiselect.view.select(roles);
	    	this.rolesField.fromTo();
    	}
    	
	    this.form.getForm().loadRecord(this.record);
    },
    
    /**
     * 
     */
    onRegisterOrUpdateUser: function(b, e) {
    	if (!this.form.getForm().isValid()) {
            this.application.setAlert(false, "Formulario inv&aacute;lido.");
            return false;
        }
    	
    	var values = this.form.getForm().getValues();
    	delete values.cpassword;
    	
    	//var hash = hex_md5( values.hiddenSeed + hex_md5(values.password) );
    	var hash = hex_md5(values.password);
    	this.form.getForm().setValues({password: '', cpassword: '', encrytedPassword: hash});
    	
    	if( values.status == undefined ) {
    		values.status = 'off';
    	}
    	
    	// if the event is executed for Register purpose the record must be a new one, 
    	// otherwise it must be the selected one.
    	if( this.registerButton.getText() == this.buttonRegisterText ) {
	    	this.record = new this.grid.store.recordType({
	    		username: values.username,
	    		encrytedPassword: hash,
	            email: values.email,
	            status: values.status,
	            roles: values.roles
	        });
	    	this.grid.store.add(this.record);
	    	// TODO: after added the record we must clear all field in the form
	    	// find some way to do it because reset() does not works
	    	this.form.getForm().reset();
    	}
    	else {
    		this.form.getForm().updateRecord(this.record);
    	}
    	
    	this.grid.store.save();
    },
    
    /**
     * 
     */
    setFieldsConfiguration: function(configType) {
    	if( configType == 'default' ) {
            if( this.registerButton.getText() != this.buttonRegisterText ) {
	            this.usernameField.vtype = 'uniqueusername';
	        	this.emailField.vtype = 'uniqueemail';
	        	this.passwordField.allowBlank = false;
	        	this.password2Field.allowBlank = false;
	        	this.registerButton.getEl().puff();
	            this.registerButton.setText(this.buttonRegisterText);
	            this.registerButton.getEl().slideIn();
	            
	            if( this.form.findById(this.currentPasswordField.getId()) ) {
		            this.form.remove(this.currentPasswordField);
		        	this.form.doLayout();
	            }
            }
    	}
    	else {
    		if( this.registerButton.getText() != this.buttonUpdateText ) {
	    		this.usernameField.vtype = 'alphanum';
	        	this.emailField.vtype = 'email';
	        	this.passwordField.allowBlank = true;
	        	this.password2Field.allowBlank = true;
	        	
	        	this.registerButton.getEl().puff();
	        	this.registerButton.setText(this.buttonUpdateText);
	        	this.registerButton.getEl().slideIn();
	        	
	        	//this.form.findById(this.usernameField.getId())
	        	//this.form.insert(1, this.currentPasswordField);
	        	//this.form.add(this.currentPasswordField);
	        	//this.form.doLayout();
    		}
    	}
    },
    
    /**
     * function handler used in the grid add new user button
     */
    onAddNewUser: function() {
		// retrieve the UserManager dialog
		var umObject = this.ownerCt.ownerCt.ownerCt;
		
		// deselect the selected row if there is someone selected
		var record = umObject.grid.getSelectionModel().getSelected();
		var index = umObject.grid.store.indexOf(record);
		umObject.grid.getSelectionModel().deselectRow(index);
		
		if( umObject.form.getForm().isDirty() ) {
			
		}
		
		if( umObject.registerButton.getText() != this.buttonRegisterText ) {
			umObject.setFieldsConfiguration('default');
		}
        
        //umObject.form.getForm().loadRecord(defaultRecord);
        umObject.rolesField.reset();
        umObject.password2Field.reset();
        umObject.usernameField.setValue('usuario');
        umObject.usernameField.getEl().highlight();
        umObject.usernameField.selectText();
        umObject.usernameField.focus();
        umObject.emailField.setValue('usuario@dominio.com');
    },
    
    clearFields: function() {
    	this.rolesField.reset();
    	this.passwordField.reset();
    	this.password2Field.reset();
    	this.emailField.reset();
    	this.usernameField.setValue('');
    	this.activeField.reset();
    },
    
    onShowWindow: function(userDialog) {
    	
    },
    
    // event used to handle the onChange on fields
    onChange: function( field, newValue, oldValue ) {
    	console.log(field.fieldLabel);
    	console.log('newvalue: ' + newValue + ' --> oldvalue: ' + oldValue);
//    	console.log('onChange');
//    	console.log(this.isDirty());
    }
    
});
